home *** CD-ROM | disk | FTP | other *** search
/ Deutsche Edition 1 / Deutsche Edition 1.iso / amok / 071-080 / amok71 / nodefilter1.2a / nodefilter.mod < prev    next >
Text File  |  1993-11-04  |  12KB  |  403 lines

  1. (* ------------------------------------------------------------------------
  2.   :Program.       NodeFilter
  3.   :Contents.      generate filtered Fido-BBS-List from NodeList
  4.   :Author.        Kai Bolay [kai]
  5.   :Address.       Hoffmannstraße 168
  6.   :Address.       D-7250 Leonberg 1
  7.   :History.       v0.1  [kai] 15-May-91 (initial)
  8.   :History.       v0.2  [kai] 19-May-91 (- Host-bug)
  9.   :History.       v0.3  [kai] 20-May-91 (+ speed, + Flags, ...)
  10.   :History.       v1.0  [kai] 22-May-91 (Flags OK, variable output, rework)
  11.   :History.       v1.1  [kai] 23-May-91 (cosmetic, bug fixes, time)
  12.   :History.       v1.2  [kai] 24-May-91 (2.0 pattern-matching if available
  13.                                         more chars, new address-output)
  14.   :History.       v1.2a [kai] 24-Apr-92 recompiled
  15.   :Copyright.     © 1991-92 by Kai Bolay
  16.   :Copyright.     distribution allowed for non-comercial purposes
  17.   :Language.      Oberon
  18.   :Translator.    AMIGA OBERON v2.25d, A+L AG
  19.   :Imports.       StringOps [bne], PatMatch [kai]/Bernd Preusing
  20.   :Remark.        created for Jörg Henner
  21. ------------------------------------------------------------------------ *)
  22. MODULE NodeFilter;
  23.  
  24. IMPORT
  25.    fs: FileSystem, a:Arguments, ng: NoGuru, io, so: StringOps, Break,
  26.    pat: PatMatch, d: Dos;
  27. CONST
  28.    Version = "\[1mNodeFilter\[21;3m v1.2a\[23;32m by Kai Bolay\[0m\n\n\o"
  29.              "$VER: NodeFilter 1.2a (24-Apr-92)\r\n";
  30.    ticksPerMinute = d.ticksPerSecond * 60;
  31.    ticksPerHour   = ticksPerMinute * 60;
  32.    ticksPerDay    = ticksPerHour * 24;
  33.  
  34.    CM   =  0;
  35.    MO   =  1;
  36.    HST  =  2;
  37.    XA   =  3;
  38.    V42B =  4;
  39.    V32B =  5;
  40.    V21  =  6;
  41.    V22  =  7;
  42.    V32  =  8;
  43.    V42  =  9;
  44.    MNP  = 10;
  45.    XX   = 11;
  46.    XB   = 12;
  47.    XW   = 13;
  48.    XR   = 14;
  49.    PEP  = 15;
  50.  
  51.    Funct = 0;
  52.    Name  = 1;
  53.    City  = 2;
  54.    Sysop = 3;
  55.    Phone = 4;
  56.    Baud  = 5;
  57.    Flags = 6;
  58.    Zone  = 7;
  59.    Net   = 8;
  60.    Node  = 9;
  61.    Num   = 10;
  62.    
  63.    StrLen = 150;
  64.  
  65. VAR
  66.    NodeName, BBSName: ARRAY 30 OF CHAR;
  67.    NodeFile, BBSFile: fs.File;
  68.    NodeOpen, BBSOpen: BOOLEAN;
  69.    Input, Output: ARRAY 256 OF CHAR;
  70.    Flag: ARRAY 30 OF CHAR;
  71.    Now, Then: d.Date;
  72.  
  73.    Desc:  ARRAY Num OF ARRAY 10 OF CHAR;
  74.    Check: ARRAY Num OF BOOLEAN;
  75.    Pat:   ARRAY Num OF ARRAY StrLen OF CHAR;
  76.    Aux:   ARRAY Num OF ARRAY StrLen OF SHORTINT;
  77.    Str:   ARRAY Num OF ARRAY StrLen OF CHAR;
  78.    Width: ARRAY Num OF INTEGER;
  79.  
  80.    NewZone, NewNet, Ok, Prompt, Stat, NewOS, Addr: BOOLEAN;
  81.    Comma, Pos, Line, Len, i, j: INTEGER;
  82.    CurZone, CurNet: ARRAY 5 OF CHAR;
  83.    CurFlags, WantFlags: LONGSET;
  84.    li: LONGINT;
  85.  
  86.    ZoneCount, RegionCount, HostCount, HubCount, DownCount,
  87.    PvtCount, HoldCount, NodeCount, BBSCount: INTEGER;
  88.  
  89. PROCEDURE GetStr (k: INTEGER);
  90. BEGIN
  91.    Comma := so.FindChar (Input, ',', Pos);
  92.    IF Comma = -1 THEN
  93.       io.WriteString ("\nLine"); io.WriteInt (Line, 5);
  94.       io.WriteString (": expected "); io.WriteString (Desc[k]); io.WriteLn;
  95.       HALT (20);
  96.    END; (* IF *)
  97.    so.SubString (Input, Str[k], Pos, Comma-Pos);
  98.    Pos := Comma+1;
  99. END GetStr;
  100.  
  101. PROCEDURE GetFlags (VAR FlagSet: LONGSET);
  102. VAR
  103.    Found: BOOLEAN;
  104.  
  105.    PROCEDURE TestFlag (s: ARRAY OF CHAR; f: INTEGER);
  106.    BEGIN
  107.       IF (NOT Found) AND (Flag = s) THEN
  108.          INCL (FlagSet, f); Found := TRUE;
  109.       END; (* IF *)
  110.    END TestFlag;
  111.  
  112. BEGIN
  113.    FlagSet := LONGSET {};
  114.    LOOP
  115.       Comma := so.FindChar (Input, ',', Pos);
  116.       IF Comma = -1 THEN EXIT END;
  117.       so.SubString (Input, Flag, Pos, Comma-Pos);
  118.       Pos := Comma+1;
  119.       Found := FALSE;
  120.       TestFlag ("CM",   CM  );
  121.       TestFlag ("MO",   MO  );
  122.       TestFlag ("HST",  HST );
  123.       TestFlag ("XA",   XA  );
  124.       TestFlag ("V42B", V42B);
  125.       TestFlag ("V32B", V32B);
  126.       TestFlag ("V21",  V21 );
  127.       TestFlag ("V22",  V22 );
  128.       TestFlag ("V32",  V32 );
  129.       TestFlag ("V42",  V42 );
  130.       TestFlag ("MNP",  MNP );
  131.       TestFlag ("XX",   XX  );
  132.       TestFlag ("XB",   XB  );
  133.       TestFlag ("XW",   XW  );
  134.       TestFlag ("XR",   XR  );
  135.       TestFlag ("PEP",  PEP );
  136.       IF NOT Found THEN
  137.          (* Unknown Flag *)
  138.       END; (* IF *)
  139.    END; (* LOOP *)
  140. END GetFlags;
  141.  
  142. PROCEDURE Display (k: INTEGER);
  143. VAR
  144.    len: INTEGER;
  145. BEGIN
  146.    IF Width[k] > 1 THEN
  147.       len := so.Length (Output);
  148.       so.Append (Output, Str[k]);
  149.       Output[len+Width[k]-1] := 0X;
  150.       so.AppendBlanks (Output, len+Width[k]);
  151.    END; (* IF *)
  152. END Display;
  153.  
  154. PROCEDURE WriteCount (str: ARRAY OF CHAR; cnt: INTEGER);
  155. BEGIN
  156.    io.WriteString ("processed"); io.WriteInt (cnt, 6);
  157.    io.WriteString (str); io.WriteLn;
  158. END WriteCount;
  159.  
  160.  
  161. BEGIN
  162.    Desc[Zone]  := "Zone";
  163.    Desc[Net]   := "Net";
  164.    Desc[Node]  := "Node";
  165.    Desc[Name]  := "Name";
  166.    Desc[City]  := "City";
  167.    Desc[Sysop] := "Sysop";
  168.    Desc[Phone] := "Phone";
  169.    Desc[Baud]  := "Baud";
  170.    Desc[Flags] := "Flags";
  171.    Desc[Funct] := "Funct";
  172.    NodeOpen := FALSE; BBSOpen := FALSE; Stat := FALSE;
  173.    NewOS := d.dos.lib.version >= 37;
  174.    Prompt := d.IsInteractive (io.in);
  175.    d.DateStamp (Then);
  176.  
  177.    io.WriteString (Version);
  178.    IF a.NumArgs() # 2 THEN
  179.       io.WriteString ("Usage: NodeFilter NodeList/A BBSList/A");
  180.       IF (a.NumArgs() = 1) THEN
  181.          a.GetArg (1, NodeName);
  182.          IF NodeName = "?" THEN
  183.             io.WriteString ("\nNodeList: input file, a valid Fido-nodelist\n");
  184.             io.WriteString ("BBSList: output file, created by NodeFilter\n");
  185.             io.WriteString ("\nUse this program to filter the nodelist for interesting\n");
  186.             io.WriteString ("informations. Use AmigaDOS-style pattern-matching!");
  187.          END; (* IF *)
  188.       END; (* IF *)
  189.       HALT (20);
  190.    END; (* IF *)
  191.  
  192.    a.GetArg (1, NodeName);
  193.    ng.Assert (fs.Open (NodeFile, NodeName, FALSE),
  194.               "Unable to open NodeList!");
  195.    NodeOpen := TRUE;
  196.  
  197.    a.GetArg (2, BBSName);
  198.    ng.Assert (fs.Open (BBSFile, BBSName, TRUE),
  199.               "Unable to open BBSList!");
  200.    BBSOpen := TRUE;
  201.  
  202.    IF Prompt THEN
  203.       io.WriteString ("Use Amiga-DOS pattern-matching. <RETURN> for all!\n");
  204.       io.WriteString ("Width defines output-format. <RETURN> -> No Output\n");
  205.       io.WriteString ("Enter Flags seperated by commas (e.g. 'MO,HST')\n\n");
  206.    END; (* IF *)
  207.    i := 0;
  208.    REPEAT
  209.       IF Prompt THEN
  210.          so.Concat ("", Desc[i], Output);
  211.          so.Append (Output, ":"); so.AppendBlanks (Output, 15);
  212.       END; (* IF *)
  213.       IF i # Flags THEN
  214.          IF Prompt THEN
  215.             so.Append (Output, "Pattern: "); io.WriteString (Output);
  216.          END; (* IF *)
  217.          io.ReadString (Pat[i]);
  218.          j := so.FindChar (Pat[i], ';', 0);
  219.          IF j # -1 THEN Pat[i][j] := 0X END;
  220.          so.CutBlanks (Pat[i]);
  221.          Check[i] := (Pat[i][0] # 0X) AND (Pat[i] # "*") AND
  222.                      (Pat[i] # "#?");
  223.          IF Check[i] THEN
  224.             IF NewOS THEN
  225.                COPY (Pat[i], Input);
  226.                ng.Assert (d.ParsePatternNoCase (Input, Pat[i], StrLen) # -1,
  227.                           "pattern error!");
  228.             ELSE
  229.                ng.Assert (pat.CmplPat (Pat[i], Aux[i]), "pattern error!");
  230.             END; (* IF *)
  231.          END; (* IF *)
  232.       ELSE
  233.          IF Prompt THEN
  234.             so.Append (Output, "Flags:   "); io.WriteString (Output);
  235.          END; (* IF *)
  236.          io.ReadString (Input);
  237.          j := so.FindChar (Input, ';', 0);
  238.          IF j # -1 THEN Input[j] := 0X END;
  239.          so.CutBlanks (Input);
  240.          Check[Flags] := Input # "";
  241.          IF Check[Flags] THEN
  242.             so.AppendChar (Input, ',');
  243.             GetFlags (WantFlags);
  244.          END; (* IF *)
  245.       END; (* IF *)
  246.  
  247.       IF (i # Node) AND (i # Net) AND (i # Zone) THEN
  248.          IF Prompt THEN
  249.             io.WriteString ("       Width:   ");
  250.          END; (* IF *)
  251.          io.ReadString (Input);
  252.  
  253.          j := so.FindChar (Input, ';', 0);
  254.          IF j # -1 THEN Input[j] := 0X END;
  255.          so.CutBlanks (Input);
  256.          ng.Assert (so.StrToIntOk (Input, li), "integer error!");
  257.          Width[i] := SHORT (li);
  258.       END; (* IF *)
  259.  
  260.       INC (i);
  261.       IF Prompt THEN io.WriteLn END;
  262.    UNTIL (i = Num);
  263.  
  264.    IF Prompt THEN
  265.       io.WriteString ("       Address: ");
  266.    END; (* IF *)
  267.    io.ReadString (Input);
  268.    j := so.FindChar (Input, ';', 0);
  269.    IF j # -1 THEN Input[j] := 0X END;
  270.    so.CutBlanks (Input);
  271.    ng.Assert ((Input[0] = 'y') OR (Input[0] = 'n'), "only y/n!");
  272.    Addr := Input[0] = 'y';
  273.  
  274.    Stat := TRUE;
  275.    d.DateStamp (Then);
  276.    Line := 0;
  277.    LOOP
  278.       REPEAT
  279.          IF NOT fs.ReadString (NodeFile, Input) THEN EXIT END;
  280.          INC (Line);
  281.          IF Line MOD 100 = 0 THEN io.Write ('.') END;
  282.       UNTIL Input[0] # ';';
  283.       j := so.Length (Input);
  284.       IF j > 1 THEN Input[j-1] :=  ',' END;
  285.       Pos := 0;
  286.       GetStr (Funct);
  287.       NewZone := FALSE;
  288.       NewNet := FALSE;
  289.       IF Str[Funct] = "" THEN
  290.          INC (NodeCount);
  291.       ELSIF Str[Funct] = "Zone" THEN
  292.          INC (ZoneCount);
  293.          NewZone := TRUE;
  294.          NewNet := TRUE;
  295.       ELSIF Str[Funct] = "Region" THEN
  296.          INC (RegionCount);
  297.          NewNet := TRUE;
  298.       ELSIF Str[Funct] = "Host" THEN
  299.          INC (HostCount);
  300.          NewNet := TRUE;
  301.       ELSIF Str[Funct] = "Hub" THEN
  302.          INC (HubCount);
  303.       ELSIF Str[Funct] = "Down" THEN
  304.          INC (DownCount);
  305.       ELSIF Str[Funct] = "Pvt" THEN
  306.          INC (PvtCount);
  307.       ELSIF Str[Funct] = "Hold" THEN
  308.          INC (HoldCount);
  309.       ELSE
  310.          io.WriteString ("\nLine"); io.WriteInt (Line, 5);
  311.          io.WriteString (": Eh, what's '"); io.WriteString (Str[Funct]);
  312.          io.WriteString ("' ???"); HALT (20);
  313.       END; (* IF *)
  314.       GetStr (Node);
  315.       IF NewZone THEN COPY (Str[Node], CurZone) END;
  316.       IF NewNet THEN COPY (Str[Node], CurNet); Str[Node] := "0" END;
  317.       COPY (CurZone, Str[Zone]);
  318.       COPY (CurNet, Str[Net]);
  319.  
  320.       i := Name;
  321.       REPEAT
  322.          GetStr (i);
  323.          INC (i);
  324.       UNTIL i = Flags;
  325.  
  326.       (* whole Flags! *)
  327.       so.SubString (Input, Str[i], Pos, so.Length (Input)-Pos-1);
  328.  
  329.       GetFlags (CurFlags);
  330.  
  331.       Ok := TRUE; i := 0;
  332.       REPEAT
  333.          IF i = Flags THEN
  334.             Ok := ((NOT Check[i])  OR (CurFlags * WantFlags = WantFlags));
  335.          ELSE
  336.             IF NewOS THEN
  337.                Ok := ((NOT Check[i]) OR d.MatchPatternNoCase (Pat[i], Str[i]));
  338.             ELSE
  339.                Ok := ((NOT Check[i]) OR pat.Match (Pat[i], Aux[i], Str[i]));
  340.             END; (* IF *)
  341.          END; (* IF *)
  342.          INC (i);
  343.       UNTIL (i = Num) OR NOT Ok;
  344.       IF Ok THEN
  345.          Output := "";
  346.          i := 0;
  347.          REPEAT
  348.             IF (i # Node) AND (i # Net) AND (i # Zone) THEN
  349.                Display (i);
  350.             END; (* IF *)
  351.             INC (i);
  352.          UNTIL i = Num;
  353.          IF Addr THEN
  354.             so.AppendChar (Output, '(');
  355.             so.Append (Output, Str[Zone]);
  356.             so.AppendChar (Output, ':');
  357.             so.Append (Output, Str[Net]);
  358.             so.AppendChar (Output, '/');
  359.             so.Append (Output, Str[Node]);
  360.             so.AppendChar (Output, ')');
  361.          END; (* IF *)
  362.          ng.Assert (fs.WriteString (BBSFile, Output),
  363.                     "Error writing BBSFile!");
  364.          INC (BBSCount);
  365.       END; (* IF *)
  366.    END; (* LOOP *)
  367. CLOSE
  368.    d.DateStamp (Now);
  369.    IF NodeOpen THEN
  370.       ng.Assert (fs.Close (NodeFile), "Unable to close NodeList!");
  371.    END; (* IF *)
  372.    IF BBSOpen THEN
  373.       ng.Assert (fs.Close (BBSFile),  "Unable to close BBSFile!");
  374.    END; (* IF *)
  375.    IF Stat THEN
  376.       io.WriteString ("\n\nStatistics:\n\n");
  377.       WriteCount (" Zones",   ZoneCount);
  378.       WriteCount (" Regions", RegionCount);
  379.       WriteCount (" Hosts",   HostCount);
  380.       WriteCount (" Hubs",    HubCount);
  381.       WriteCount (" Downs",   DownCount);
  382.       WriteCount (" Pvts",    PvtCount);
  383.       WriteCount (" Holds",   HoldCount);
  384.       WriteCount (" Nodes",   NodeCount);
  385.       io.WriteString ("It took");
  386.       li := ((Now.tick   - Then.tick)                    +
  387.              (Now.minute - Then.minute) * ticksPerMinute +
  388.              (Now.days   - Then.days)   * ticksPerDay) DIV d.ticksPerSecond;
  389.       io.WriteInt (li, 4); io.WriteString (" secs to scan");
  390.       io.WriteInt (Line, 6); io.WriteString (" lines =>");
  391.       IF li # 0 THEN
  392.          io.WriteInt (Line DIV li, 4);
  393.          io.WriteString (" lines per second...\n");
  394.       ELSE
  395.          io.WriteString (" ---\n");
  396.       END; (* IF *)
  397.       io.WriteString ("list contains"); io.WriteInt (BBSCount, 6);
  398.       io.WriteString (" BBSs!\n\n");
  399.    ELSE
  400.       io.WriteLn; io.WriteLn;
  401.    END; (* IF *)
  402. END NodeFilter.
  403.